package oop封装;

import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 在线聊天室：客户端
 * 目标：实现oop封装结构，多用户收发消息
 */
public class Chat {
    private static CopyOnWriteArrayList<Send> all = new CopyOnWriteArrayList<>();
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("-----------Server------------");
        while (true){
            Socket socket = serverSocket.accept();//阻塞式接收
            System.out.println("一个客户端建立了连接");
            Send c = new Send(socket);
            all.add(c);
            new Thread(c).start();
        }

    }
    static class Send implements Runnable{
        private Socket client;
        private DataInputStream dis;
        private DataOutputStream dos;
        private boolean isRunning;
        private String name;
        public Send(Socket client){
            this.client = client;
            try {
                dos = new DataOutputStream(client.getOutputStream());
                dis = new DataInputStream(client.getInputStream());
                isRunning = true;
                this.name = receive();
                this.sendOrther(this.name+"来到了聊天室",false);
            } catch (IOException e) {
                //关闭
                closeAll(client,dos,dis);
            }
        }
        //接收消息
        public String receive(){
            String mag = "";
            try {
               mag = dis.readUTF();
               return mag;
            } catch (IOException e) {
                closeAll(client,dos,dis);
            }
            return "";
        }

        //群聊
        //私聊
        public void sendOrther(String mag, boolean isboorea){//对mag进行判断
            if (mag.startsWith("@")){
                int index = mag.indexOf(":");
                String a = mag.substring(1,index);
                mag = mag.substring(index+1);
                for (Send s: all){
                    if (s.name.equals(a)){
                        s.send(this.name +"私聊你说："+mag);
                    }
                }
            }else {
                for (Send s: all){
                    if (s == this){ //表示遍历到了自己（排他思想）
                        continue;
                    }else {
                        if (isboorea){//true代表对所有人说
                            s.send(this.name +"对所有人说："+mag);
                        }else {
                            //false代表系统的通知
                            s.send(mag);
                        }

                    }
                }
            }

        }
        //发送信息
        public void send(String mag){
            try {
                if (!mag.equals("")){
                    dos.writeUTF(mag);
                    dos.flush();
                }else {
                    closeAll(client,dis,dos);
                }
            } catch (IOException e) {
                closeAll(client,dis,dos);
            }
        }
        //释放资源
        public void closeAll(Closeable...closeables){
            for (Closeable close: closeables) {
                    try {
                        if (null != close) {
                            close.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
            isRunning = false;
            all.remove(this);
            sendOrther(this.name+"离开了聊天室",false);
        }
        //多线程
        @Override
        public void run() {
            while (isRunning){
                //接收消息
               String mag = receive();
                if (mag == null){
                    closeAll(client,dis,dos);
                }else {
                    //发送消息
                    sendOrther(mag,true);
                }
            }
        }
    }
}
